#include "configuredialog.h"
#include "ui_configuredialog.h"
#include <QDebug>
#include <QMessageBox>
#include <QFileDialog>
#include <QLibrary>
#include <QSqlError>

ConfigureDialog::ConfigureDialog(QSettings *set, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ConfigureDialog),
    settings(set),
    modelConnections(new QStandardItemModel(0, 6, this)),
    modelPlugin(new QStandardItemModel(0,4)),
    db(QSqlDatabase::addDatabase("QMYSQL","dbRebuild")),
    createDb(QStringList())
{
    if (settings == 0) {
        qWarning() << tr("Internal error");
        quick_exit(255);
    }
    ui->setupUi(this);
    ui->listViewConnections->addAction(ui->actionAdd_database);
    ui->actionAdd_database->setIcon(QIcon::fromTheme("list-add"));
    ui->listViewConnections->addAction(ui->actionDelete_database);
    ui->actionDelete_database->setIcon(QIcon::fromTheme("list-remove"));
    QAction *actionSeparate = new QAction(this);
    actionSeparate->setSeparator(true);
    ui->listViewConnections->addAction(actionSeparate);
    ui->listViewConnections->addAction(ui->actionDatabaseSelect_for_use);
    ui->actionDatabaseSelect_for_use->setIcon(QIcon::fromTheme("network-server-database"));
    ui->listViewConnections->setModel(modelConnections);
    connect(ui->listViewConnections, SIGNAL(clicked(QModelIndex)), this, SLOT(modelIndexChange(QModelIndex)));
    ui->toolButtonSetPluginPath->setIcon(QIcon::fromTheme("document-open-executable"));
    ui->tableViewPlugins->setContextMenuPolicy(Qt::ActionsContextMenu);
    ui->tableViewPlugins->addAction(ui->actionPluginReload_plugins);
    ui->tableViewPlugins->addAction(ui->actionPluginSwitch_state);
    ui->tableViewPlugins->addAction(actionSeparate);
    ui->tableViewPlugins->addAction(ui->actionPluginDatabase_rebuild);
    ui->actionPluginReload_plugins->setIcon(QIcon::fromTheme("view-refresh"));
    ui->actionPluginSwitch_state->setIcon(QIcon::fromTheme("checkbox"));
    ui->actionPluginDatabase_rebuild->setIcon(QIcon::fromTheme("dialog-warning"));
    QStringList slistPluginHeaders;
    slistPluginHeaders << tr("Name") << tr("VRSV code") << tr("version") << tr("file");

    modelPlugin->setHorizontalHeaderLabels(slistPluginHeaders);
    ui->tableViewPlugins->setModel(modelPlugin);
    ui->tableViewPlugins->setColumnWidth(0,170);
    ui->tableViewPlugins->setColumnWidth(1,130);
    ui->tableViewPlugins->setColumnWidth(2,100);
    ui->tableViewPlugins->setColumnWidth(3,200);
    ui->tableViewPlugins->setSelectionMode(QAbstractItemView::SingleSelection);

    updateData();

    ///create Db
    QString t_gender_drop = QString("DROP TABLE IF EXISTS `gender`;");
    QString t_gender_create = QString("CREATE TABLE `gender` (`id` INT PRIMARY KEY AUTO_INCREMENT, `title` VARCHAR(6) NOT NULL);");
    QString t_gender_insert = QString("INSERT INTO `gender`(`title`) VALUES ('" + tr("Male") + "');") +
            QString("INSERT INTO `gender`(`title`) VALUES ('" + tr("Female") + "');") +
            QString("INSERT INTO `gender`(`title`) VALUES ('" + tr("All") + "');");
    QString v_gender_member = QString("CREATE OR REPLACE VIEW `gender_member` as select * from gender where `title` != '" + tr("All") + "';");

    QString t_range_drop = QString("DROP TABLE IF EXISTS `sport_range`;");
    QString t_range_create = QString("CREATE TABLE `sport_range` (`id` INT PRIMARY KEY AUTO_INCREMENT,`title` VARCHAR(15) NOT NULL UNIQUE);");
    QString t_range_insert = QString("INSERT INTO `sport_range`(`title`) VALUES ('" + tr("None") + "');") +
            QString("INSERT INTO `sport_range`(`title`) VALUES ('" + tr("3-range") + "');") +
            QString("INSERT INTO `sport_range`(`title`) VALUES ('" + tr("2-range") + "');") +
            QString("INSERT INTO `sport_range`(`title`) VALUES ('" + tr("1-range") + "');") +
            QString("INSERT INTO `sport_range`(`title`) VALUES ('" + tr("CMS") + "');") +
            QString("INSERT INTO `sport_range`(`title`) VALUES ('" + tr("MS") + "');") +
            QString("INSERT INTO `sport_range`(`title`) VALUES ('" + tr("MS WC") + "');");

    QString t_member_drop = QString("DROP TABLE IF EXISTS `member`;");
    QString t_member_create = QString("CREATE TABLE `member` (`id` INT PRIMARY KEY AUTO_INCREMENT,`name` VARCHAR(75) NOT NULL, `dob` DATE NOT NULL, `range` INT NOT NULL DEFAULT 1, `gender` INT NOT NULL DEFAULT 1, ") +
            QString("INDEX `fk_member_range`(`range` ASC), CONSTRAINT `fk_member_range` FOREIGN KEY (`range` ) REFERENCES `sport_range` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE, ") +
            QString("INDEX `fk_member_gender`(`gender` ASC), CONSTRAINT `fk_member_gender` FOREIGN KEY (`gender` ) REFERENCES `gender` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE);");
    QString t_team_drop = QString("DROP TABLE IF EXISTS `team`;");
    QString t_team_create = QString("CREATE TABLE `team` (`id` INT PRIMARY KEY AUTO_INCREMENT,`title` VARCHAR(45) NOT NULL UNIQUE, `organization` VARCHAR(75) DEFAULT NULL);");
    QString t_member_team_drop = QString("DROP TABLE IF EXISTS `team_member`;");
    QString t_member_team_create = QString("CREATE TABLE `team_member` (`id` INT PRIMARY KEY AUTO_INCREMENT,`member` INT NOT NULL, `team` INT NOT NULL, INDEX `fk_member`(`member` ASC), CONSTRAINT `fk_member` FOREIGN KEY (`member` ) REFERENCES `member` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE , INDEX `fk_team`(`team` ASC), CONSTRAINT `fk_team` FOREIGN KEY (`team` ) REFERENCES `team` (`id`) ON DELETE CASCADE ON UPDATE CASCADE);");
    QString t_difficalty_drop = QString("DROP TABLE IF EXISTS `difficalty`;");
    QString t_difficalty_create = QString("CREATE TABLE `difficalty` (`id` INT PRIMARY KEY AUTO_INCREMENT NOT NULL UNIQUE, `title` VARCHAR(3) NOT NULL UNIQUE);");
    QString t_group_drop = QString("DROP TABLE IF EXISTS `group`;");
    QString t_group_create = QString("CREATE TABLE `group` (`id` INT PRIMARY KEY AUTO_INCREMENT, `title` VARCHAR(45) NOT NULL UNIQUE, `gender` ENUM('m','f','a') NOT NULL, `min_age` INT NOT NULL, `max_age` INT NOT NULL);");
    QString t_competition_drop = QString("DROP TABLE IF EXISTS `competition`;");
    QString t_competition_create = QString("CREATE TABLE `competition` (`id` INT PRIMARY KEY AUTO_INCREMENT, `title` VARCHAR(150) NOT NULL UNIQUE, `start_date` DATE NOT NULL, `finish_date` DATE DEFAULT NULL, `cwall` VARCHAR(45) NOT NULL, `emblem` BLOB DEFAULT NULL, `main_guidge` VARCHAR(45) NOT NULL, `main_secretary` VARCHAR(45) NOT NULL, `conception` TEXT DEFAULT NULL);");
    QString t_competition_group_drop = QString("DROP TABLE IF EXISTS `competition_group`;");
    QString t_competition_group_create = QString("CREATE TABLE `competition_group` (`id` INT PRIMARY KEY AUTO_INCREMENT, `competition` INT NOT NULL, `group` INT NOT NULL, INDEX `fk_competition_group_competition`(`competition` ASC), CONSTRAINT `fk_competition_group_competition` FOREIGN KEY (`competition` ) REFERENCES `competition` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, INDEX `fk_competition_group_group`(`group` ASC), CONSTRAINT `fk_competition_group_group` FOREIGN KEY (`group` ) REFERENCES `group` (`id`) ON DELETE CASCADE ON UPDATE CASCADE);");
    QString t_member_reg_drop = QString("DROP TABLE IF EXISTS `member_reg`;");
    QString t_member_reg_create = QString("CREATE TABLE `member_reg` (`id` INT PRIMARY KEY AUTO_INCREMENT, `member` INT NOT NULL, `group` INT NOT NULL, INDEX `fk_member_reg_member`(`member` ASC), CONSTRAINT `fk_member_reg_member` FOREIGN KEY (`member` ) REFERENCES `member` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE, INDEX `fk_member_reg_group`(`group` ASC), CONSTRAINT `fk_member_reg_group` FOREIGN KEY (`group` ) REFERENCES `competition_group` (`id`) ON DELETE CASCADE ON UPDATE CASCADE);");
    QString t_tour_drop = QString("DROP TABLE IF EXISTS `tour`;");
    QString t_tour_create = QString("CREATE TABLE `tour` (`id` INT PRIMARY KEY AUTO_INCREMENT, `group` INT NOT NULL, `type` INT NOT NULL, `title` VARCHAR(100) NOT NULL, `start_time` DATETIME DEFAULT NULL, `finish_time` DATETIME DEFAULT NULL, INDEX `fk_tour_group`(`group` ASC), CONSTRAINT `fk_tour_group` FOREIGN KEY (`group` ) REFERENCES `competition_group` (`id`) ON DELETE CASCADE ON UPDATE CASCADE);");
    QString t_report_drop = QString("DROP TABLE IF EXISTS `report`;");
    QString t_report_create = QString("CREATE TABLE `report` (`id` INT PRIMARY KEY AUTO_INCREMENT, `tour` INT NOT NULL, `type` ENUM('registration','start','finish','competition') NOT NULL, `body` TEXT NOT NULL, INDEX `fk_report_tour`(`tour` ASC), CONSTRAINT `fk_report_tour` FOREIGN KEY (`tour` ) REFERENCES `tour` (`id`) ON DELETE CASCADE ON UPDATE CASCADE);");

    // inset to first
    createDb << t_report_drop << t_tour_drop << t_member_reg_drop << t_competition_group_drop << t_competition_drop << t_group_drop << t_difficalty_drop << t_member_team_drop << t_team_drop << t_member_drop << t_range_drop << t_gender_drop;
    // insert to last
    createDb << t_gender_create << t_gender_insert << v_gender_member << t_range_create << t_range_insert << t_member_create << t_team_create << t_member_team_create << t_difficalty_create << t_group_create << t_competition_create << t_competition_group_create << t_member_reg_create << t_tour_create << t_report_create;

}

ConfigureDialog::~ConfigureDialog()
{
    delete ui;
}

void ConfigureDialog::updateData()
{
    settings->beginGroup("config");
    settings->beginGroup("environment");
    ui->tableWidgetEnvironment->item(0, 1)->setText(settings->value("organization").toString());
    ui->tableWidgetEnvironment->item(1, 1)->setText(settings->value("address").toString());
    ui->tableWidgetEnvironment->item(2, 1)->setText(settings->value("phone").toString());
    ui->tableWidgetEnvironment->item(3, 1)->setText(settings->value("mail").toString());
    ui->tableWidgetEnvironment->item(4, 1)->setText(settings->value("url").toString());
    ui->tableWidgetEnvironment->item(5, 1)->setText(settings->value("director").toString());
    ui->tableWidgetEnvironment->item(6, 1)->setText(settings->value("software key", "No key").toString());
    settings->endGroup();
    ui->tableWidgetEnvironment->setColumnWidth(1, 250);
    modelConnections->removeRows(0, modelConnections->rowCount());
    QList<QVariant> connection = settings->value("connections").toList();
    if (connection.count() > 0) {
        for (int row = 0; row < connection.count(); row++) {
            modelConnections->insertRow(row);
            modelConnections->setData(modelConnections->index(row, 1),connection.at(row).toStringList().at(0));
            modelConnections->setData(modelConnections->index(row, 2),connection.at(row).toStringList().at(1));
            modelConnections->setData(modelConnections->index(row, 3),connection.at(row).toStringList().at(2));
            modelConnections->setData(modelConnections->index(row, 4),connection.at(row).toStringList().at(3));
            modelConnections->setData(modelConnections->index(row, 5),connection.at(row).toStringList().at(4));
            if (modelConnections->data(modelConnections->index(row,5)).toString().isEmpty()) modelConnections->itemFromIndex(modelConnections->index(row,0))->setCheckState(Qt::Unchecked);
            else modelConnections->itemFromIndex(modelConnections->index(row,0))->setCheckState(Qt::Checked);
        }
    }
    ui->lineEditPluginsPath->setText(settings->value("plugins path", "/usr/local/lib/cwall").toString());
    settings->beginGroup("plugins");
    settings->endGroup();
    settings->endGroup();
    updateConnettionsName();
    modelIndexChange(modelConnections->index(-1, 0));
    ui->actionDatabaseSelect_for_use->setDisabled(true);
    ui->actionDelete_database->setDisabled(true);
    on_actionPluginReload_plugins_triggered();
}

void ConfigureDialog::commitData()
{
    settings->setValue("README","PLEASE, NOT EDIT THIST");
    settings->beginGroup("config");
    settings->beginGroup("environment");
    settings->setValue("organization", ui->tableWidgetEnvironment->item(0, 1)->text());
    settings->setValue("address", ui->tableWidgetEnvironment->item(1, 1)->text());
    settings->setValue("phone", ui->tableWidgetEnvironment->item(2, 1)->text());
    settings->setValue("mail", ui->tableWidgetEnvironment->item(3, 1)->text());
    settings->setValue("url", ui->tableWidgetEnvironment->item(4, 1)->text());
    settings->setValue("director", ui->tableWidgetEnvironment->item(5, 1)->text());
    settings->setValue("software key", ui->tableWidgetEnvironment->item(6, 1)->text());
    settings->endGroup();
    QList<QVariant> connections;
    if (modelConnections->rowCount() > 0) {
        for (int row = 0; row < modelConnections->rowCount(); row++) {
            QStringList connection;
            connection.insert(connection.count(), modelConnections->data(modelConnections->index(row, 1)).toString());
            connection.insert(connection.count(), modelConnections->data(modelConnections->index(row, 2)).toString());
            connection.insert(connection.count(), modelConnections->data(modelConnections->index(row, 3)).toString());
            connection.insert(connection.count(), modelConnections->data(modelConnections->index(row, 4)).toString());
            connection.insert(connection.count(), modelConnections->data(modelConnections->index(row, 5)).toString());
            connections.insert(row,connection);
        }
    }
    settings->setValue("connections",connections);
    settings->setValue("plugins path", ui->lineEditPluginsPath->text());
    settings->beginGroup("plugins");
    if (modelPlugin->rowCount()>0) for (int row = 0; row < modelPlugin->rowCount(); row++) {
        settings->setValue(modelPlugin->index(row,3).data().toString(),
                           modelPlugin->itemFromIndex(modelPlugin->index(row,0))->checkState() == Qt::Checked);
    }
    settings->endGroup();
    settings->endGroup();
}

void ConfigureDialog::showEvent(QShowEvent *e)
{
    updateData();
    ui->toolBox->setCurrentWidget(ui->pageDatabase);
    e->accept();
}

void ConfigureDialog::on_buttonBox_clicked(QAbstractButton *button)
{
    if (button->text() == tr("Reset")) {
        updateData();
    } else if (button->text() == tr("Save")) {
        commitData();
        emit cfgUpdate();
    }
}

void ConfigureDialog::on_actionAdd_database_triggered()
{
    modelConnections->insertRow(modelConnections->rowCount());
    if (modelConnections->index(modelConnections->rowCount() - 1, 0).isValid()) {
        modelConnections->setData(modelConnections->index(modelConnections->rowCount() - 1, 1), "localhost");
        modelConnections->setData(modelConnections->index(modelConnections->rowCount() - 1, 2), "cwall");
        modelConnections->setData(modelConnections->index(modelConnections->rowCount() - 1, 3), "root");
        modelConnections->setData(modelConnections->index(modelConnections->rowCount() - 1, 4), "mysql");
        modelConnections->setData(modelConnections->index(modelConnections->rowCount() - 1, 5), "");
        updateConnettionsName();
    }
    ui->listViewConnections->setCurrentIndex(modelConnections->index(modelConnections->rowCount() - 1, 0));
    modelIndexChange(modelConnections->index(modelConnections->rowCount() - 1, 0));
}

void ConfigureDialog::on_actionDelete_database_triggered()
{
    if (QMessageBox::question(this,
                              windowTitle(),
                              tr("Delete current database entry?"),
                              QMessageBox::Yes | QMessageBox::No,
                              QMessageBox::No) == QMessageBox::Yes)
        modelConnections->removeRow(ui->listViewConnections->currentIndex().row());
    modelIndexChange(modelConnections->index(modelConnections->rowCount() - 1, 0));
}

void ConfigureDialog::modelIndexChange(QModelIndex index)
{
    ui->frame->setEnabled(index.isValid());
    if (modelConnections->rowCount() > 0) {
        ui->lineEditHost->setText(modelConnections->data(modelConnections->index(index.row(), 1)).toString());
        ui->lineEditDBase->setText(modelConnections->data(modelConnections->index(index.row(), 2)).toString());
        ui->lineEditUser->setText(modelConnections->data(modelConnections->index(index.row(), 3)).toString());
        ui->lineEditPasswd->setText(modelConnections->data(modelConnections->index(index.row(), 4)).toString());
        ui->actionDatabaseSelect_for_use->setEnabled(true);
        ui->actionDelete_database->setEnabled(true);
    } else {
        ui->lineEditHost->clear();
        ui->lineEditDBase->clear();
        ui->lineEditUser->clear();
        ui->lineEditPasswd->clear();
    }
    updateConnettionsName();
    ui->pushButtonBuildDatabase->setDisabled(true);
}

void ConfigureDialog::updateConnettionsName()
{
    for (int row = 0; row < modelConnections->rowCount(); row++) {
        if (modelConnections->index(row, 0).isValid()) {
            modelConnections->setData(modelConnections->index(row, 0),
                           "mysql://" +
                           modelConnections->data(modelConnections->index(row, 3)).toString() +
                           "@" + modelConnections->data(modelConnections->index(row, 1)).toString() +
                           "/" + modelConnections->data(modelConnections->index(row, 2)).toString());
        }
        if (modelConnections->data(modelConnections->index(row,5)).toString().isEmpty()) modelConnections->itemFromIndex(modelConnections->index(row,0))->setCheckState(Qt::Unchecked);
        else modelConnections->itemFromIndex(modelConnections->index(row,0))->setCheckState(Qt::Checked);
        modelConnections->itemFromIndex(modelConnections->index(row,0))->setCheckable(true);

    }
    ui->pushButtonTestConnection->setEnabled((!ui->lineEditHost->text().isEmpty()) &
                                             (!ui->lineEditDBase->text().isEmpty()) &
                                             (!ui->lineEditUser->text().isEmpty()));

}

void ConfigureDialog::on_lineEditHost_textEdited(const QString &arg1)
{
    modelConnections->setData(modelConnections->index(ui->listViewConnections->currentIndex().row(), 1), arg1);
    updateConnettionsName();
}

void ConfigureDialog::on_lineEditDBase_textEdited(const QString &arg1)
{
    modelConnections->setData(modelConnections->index(ui->listViewConnections->currentIndex().row(), 2), arg1);
    updateConnettionsName();
}

void ConfigureDialog::on_lineEditUser_textEdited(const QString &arg1)
{
    modelConnections->setData(modelConnections->index(ui->listViewConnections->currentIndex().row(), 3), arg1);
    updateConnettionsName();
}

void ConfigureDialog::on_lineEditPasswd_textEdited(const QString &arg1)
{
    modelConnections->setData(modelConnections->index(ui->listViewConnections->currentIndex().row(), 4), arg1);
}

void ConfigureDialog::on_actionDatabaseSelect_for_use_triggered()
{
    if (modelConnections->rowCount() > 0)
        for (int row = 0; row < modelConnections->rowCount(); row++) {
            if (row == ui->listViewConnections->currentIndex().row()) modelConnections->setData(modelConnections->index(row,5),"*");
            else modelConnections->setData(modelConnections->index(row,5),"");
        }
    updateConnettionsName();
}

void ConfigureDialog::on_pushButtonTestConnection_clicked()
{
    if (true)           /// @todo WTF?
    {
        db.setHostName(modelConnections->data(modelConnections->index(ui->listViewConnections->currentIndex().row(),1)).toString());
        db.setDatabaseName(modelConnections->data(modelConnections->index(ui->listViewConnections->currentIndex().row(),2)).toString());
        db.setUserName(modelConnections->data(modelConnections->index(ui->listViewConnections->currentIndex().row(),3)).toString());
        db.setPassword(modelConnections->data(modelConnections->index(ui->listViewConnections->currentIndex().row(),4)).toString());
        if (!db.isOpen()) db.open();
        if (db.isOpen()) {
            QMessageBox::information(this, tr("Database test"), tr("Database test complit"), QMessageBox::Close, QMessageBox::Close);
            ui->pushButtonBuildDatabase->setEnabled(true);
            db.close();
        } else {
            QMessageBox::critical(this, tr("Error"), tr("Database record incorrect"), QMessageBox::Close, QMessageBox::Close);
        }
    }
}

void ConfigureDialog::on_pushButtonBuildDatabase_clicked()
{
    if (QMessageBox::warning(this,
                             tr("Create database warning"),
                             tr("WARNING") + "\n" + tr("This operation clear data in selected database.")
                             + "\n" + tr("Applay this?"),
                             QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) {
        QDialog *getPasswd = new QDialog(0);
        QFrame *frame = new QFrame(getPasswd);
        QDialogButtonBox *bbox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel,Qt::Horizontal, getPasswd);
        connect(bbox, SIGNAL(accepted()), getPasswd, SLOT(accept()));
        connect(bbox, SIGNAL(rejected()), getPasswd, SLOT(reject()));
        QVBoxLayout *layout = new QVBoxLayout(getPasswd);
        QHBoxLayout *layout1 = new QHBoxLayout(frame);
        frame->setLayout(layout1);
        QLabel *label = new QLabel(tr("Enter database password"), getPasswd);
        QLineEdit *password = new QLineEdit(getPasswd);
        password->setEchoMode(QLineEdit::Password);
        frame->layout()->addWidget(label);
        frame->layout()->addWidget(password);
        getPasswd->setLayout(layout);
        getPasswd->layout()->addWidget(frame);
        getPasswd->layout()->addWidget(bbox);

        if (getPasswd->exec() and (password->text() == modelConnections->data(modelConnections->index(ui->listViewConnections->currentIndex().row(),4)).toString())) {
            emit cfgUpdate();
            buildDatabase();
        } else {
            QMessageBox::critical(this, tr("Error"), tr("Password incorrect") + "\n" + tr("Operation abort"), QMessageBox::Close, QMessageBox::Close);
        }
    }
}

bool ConfigureDialog::buildDatabase()
{
    if (modelConnections->itemFromIndex(ui->listViewConnections->currentIndex())->checkState() == Qt::Checked) emit disconnect();
    bool retcode = true;
    int row = ui->listViewConnections->currentIndex().row();
    db.setHostName(modelConnections->data(modelConnections->index(row,1)).toString());
    db.setDatabaseName(modelConnections->data(modelConnections->index(row,2)).toString());
    db.setUserName(modelConnections->data(modelConnections->index(row,3)).toString());
    db.setPassword(modelConnections->data(modelConnections->index(row,4)).toString());
    db.open();
    if (db.isOpen())
    {
        /// @todo Show progress widget and show current dbase opertion status in that widget

        ProgressDialog *progress = new ProgressDialog(tr("Build database"), this);
        progress->show();
        int step = 100 / createDb.count();    ///< @todo Add to deltrimmer plugins db entry count;
        QSqlQueryModel *qmodel = new QSqlQueryModel(this);
        bool isDbError = false;

        for (int id = 0; id < createDb.count(); id++)
        {
            qmodel->setQuery(createDb.at(id), db);
            QString sqlRet = qmodel->lastError().databaseText();
            QString logText;
            if (createDb.at(id).left(10).toUpper() == QString("DROP TABLE")) {
                logText = tr("DROP TABLE") + " " + createDb.at(id).split("`").at(1);
            } else  if (createDb.at(id).left(12).toUpper() == QString("CREATE TABLE")) {
                logText = tr("CREATE TABLE") + " " + createDb.at(id).split("`").at(1);
            } else if (createDb.at(id).split(" ").at(0).toUpper() == "INSERT") {
                logText = tr("INSERT DATA TO TABLE") + " " + createDb.at(id).split("`").at(1);
            } else  if (createDb.at(id).left(22).toUpper() == QString("CREATE OR REPLACE VIEW")) {
                logText = tr("CREATE VIEW") + " " + createDb.at(id).split("`").at(1);
            } else {
                logText = createDb.at(id);
                isDbError = true;
                id = createDb.count();
            }
            if (sqlRet.isEmpty()) sqlRet = tr("COMPLITED");
            progress->setValue(progress->value() + step, logText,  logText + " :: " + sqlRet);
        }


        /// @todo after main dbase building build database for active plugin`s


        if (!isDbError) progress->setValue(100, tr("finish"), tr("Operation finished"));

    } else {
        QMessageBox::critical(this, tr("Database error"), tr("Can`t open selected database"), QMessageBox::Close, QMessageBox::Close);
    }



    return retcode;
}

void ConfigureDialog::on_lineEditPluginsPath_editingFinished()
{
    on_actionPluginReload_plugins_triggered();
}

void ConfigureDialog::on_toolButtonSetPluginPath_clicked()
{
    QFileDialog *pluginPath = new QFileDialog(this,tr("Plugins folder"), ui->lineEditPluginsPath->text());
    pluginPath->setFilter(tr("Plugins (*.so);"));
    pluginPath->setFileMode(QFileDialog::Directory);
    if (pluginPath->exec() == QDialog::Accepted)
    {
        ui->lineEditPluginsPath->setText(pluginPath->directory().absolutePath());
        on_actionPluginReload_plugins_triggered();
    }
}

void ConfigureDialog::on_actionPluginReload_plugins_triggered()
{
    modelPlugin->removeRows(0,modelPlugin->rowCount());
    QDir *pluginDir = new QDir(ui->lineEditPluginsPath->text());
    QSqlDatabase plugdb = QSqlDatabase::addDatabase("QMYSQL","pluginDbTest");

    if (pluginDir->isAbsolute() & pluginDir->isReadable()) {
        QStringList filter;
        filter << "*.so";
        pluginDir->setNameFilters(filter);
        QStringList plugins = pluginDir->entryList(QDir::Files | QDir::NoSymLinks | QDir::Readable);
        settings->beginGroup("config");
        settings->beginGroup("plugins");
        while (plugins.count() > 0) {
            templatePlugin *plug;
            QString plugFileName = plugins.first(),
                    pluginName = tr("Undeclared"),
                    pluginCode = tr("Undeclared"),
                    pluginVersion = tr("Undeclared");
            int row = modelPlugin->rowCount();
            bool correctPlugin = false;
            QLibrary *plugin = new QLibrary(ui->lineEditPluginsPath->text() + "/" + plugFileName);
            bool isLoading = plugin->isLoaded();
            if (!isLoading) {
                correctPlugin = plugin->load();
            }

            typedef templatePlugin* (*pluginInit)();
            pluginInit pinit = (pluginInit) plugin->resolve("pinit");
            typedef void (*pluginRelease)(templatePlugin*);
            pluginRelease pdelete = (pluginRelease) plugin->resolve("prelease");

            if (pinit) {
                plug = pinit();
                plug->pluginInfo(pluginName, pluginCode, pluginVersion);
            } else {
                pluginName= tr("Error");
                pluginCode= tr("Error");
                pluginVersion = tr("Error");
            }

            modelPlugin->insertRow(row);
            if (settings->value(plugFileName,correctPlugin).toBool() == true) modelPlugin->itemFromIndex(modelPlugin->index(row,0))->setCheckState(Qt::Checked);
            else modelPlugin->itemFromIndex(modelPlugin->index(row,0))->setCheckState(Qt::Unchecked);
            modelPlugin->itemFromIndex(modelPlugin->index(row,0))->setCheckable(correctPlugin);
            if (correctPlugin) {
                for (int Crow = 0; Crow < modelConnections->rowCount(); Crow++) {
                    if (modelConnections->itemFromIndex(modelConnections->index(Crow,0))->checkState() == Qt::Checked) {
                        plugdb.setHostName(modelConnections->data(modelConnections->index(Crow,1)).toString());
                        plugdb.setDatabaseName(modelConnections->data(modelConnections->index(Crow,2)).toString());
                        plugdb.setUserName(modelConnections->data(modelConnections->index(Crow,3)).toString());
                        plugdb.setPassword(modelConnections->data(modelConnections->index(Crow,4)).toString());
                        plugdb.open();
                    }
                }
                if (plug->testDatabaseStructure(&plugdb)) {
                    modelPlugin->itemFromIndex(modelPlugin->index(row,0))->setIcon(QIcon::fromTheme("preferences-plugin"));
                } else {
                    modelPlugin->itemFromIndex(modelPlugin->index(row,0))->setIcon(QIcon::fromTheme("dialog-warning"));
                    modelPlugin->itemFromIndex(modelPlugin->index(row,0))->setToolTip(tr("Plugin database not corrected.") +
                                                                                      "\n" + tr("Rebuild plugin database"));
                    modelPlugin->itemFromIndex(modelPlugin->index(row,0))->setCheckState(Qt::Unchecked);

                }
                plugdb.close();
            } else {
                modelPlugin->itemFromIndex(modelPlugin->index(row,0))->setIcon(QIcon::fromTheme("dialog-cancel"));
            }
            modelPlugin->setData(modelPlugin->index(row,3),plugFileName);
            for (int col = 0; col < modelPlugin->columnCount(); col++) modelPlugin->itemFromIndex(modelPlugin->index(row,col))->setEditable(false);
            modelPlugin->setData(modelPlugin->index(row,0),pluginName);
            modelPlugin->setData(modelPlugin->index(row,1),pluginCode);
            modelPlugin->itemFromIndex(modelPlugin->index(row,1))->setTextAlignment(Qt::AlignCenter);
            modelPlugin->setData(modelPlugin->index(row,2),pluginVersion);
            modelPlugin->itemFromIndex(modelPlugin->index(row,2))->setTextAlignment(Qt::AlignCenter);

            if (plug) {
                pdelete(plug);
                plug = 0;
            }
            if (!isLoading) plugin->unload();
            plugins.removeFirst();
        }
        settings->endGroup();
        settings->endGroup();
    } else {
        QMessageBox::critical(this, tr("Critical error"), tr("Uncorrect plugin folder path"), QMessageBox::Close, QMessageBox::Close);
    }
    QSqlDatabase::removeDatabase("pluginDbTest");
}

void ConfigureDialog::on_actionPluginDatabase_rebuild_triggered()
{
    emit disconnect();
    QSqlDatabase plugdb = QSqlDatabase::addDatabase("QMYSQL","pluginDbRebuild");
    for (int row = 0; row < modelConnections->rowCount(); row++) {
        if (modelConnections->itemFromIndex(modelConnections->index(row,0))->checkState() == Qt::Checked) {
            plugdb.setHostName(modelConnections->data(modelConnections->index(row,1)).toString());
            plugdb.setDatabaseName(modelConnections->data(modelConnections->index(row,2)).toString());
            plugdb.setUserName(modelConnections->data(modelConnections->index(row,3)).toString());
            plugdb.setPassword(modelConnections->data(modelConnections->index(row,4)).toString());
            plugdb.open();
        }
    }
    if (plugdb.isOpen()) {
        QLibrary *plugin = new QLibrary(ui->lineEditPluginsPath->text() + "/" +
                                        modelPlugin->data(modelPlugin->index(ui->tableViewPlugins->currentIndex().row(), 3)).toString());
        templatePlugin *plug;
        plugin->load();
        if (plugin->isLoaded()) {
            typedef templatePlugin* (*pluginInit)();
            pluginInit pinit = (pluginInit) plugin->resolve("pinit");
            if (pinit) {
                plug = pinit();
                if (plug->buildDatabase(&plugdb)) {
                    QMessageBox::information(this, tr("Plugin information"), tr("Plugin") + " " + plugin->fileName() + " " +
                                             tr("database rebuilded"),
                                             QMessageBox::Close, QMessageBox::Close);
                } else {
                    QMessageBox::critical(this, tr("Plugin error"), tr("Don`t can execute plugin ") + plugin->fileName(), QMessageBox::Close, QMessageBox::Close);
                }
                typedef void (*pluginRelease)(templatePlugin*);
                pluginRelease pdelete = (pluginRelease) plugin->resolve("prelease");
                pdelete(plug);
                plugin->unload();
            }
        } else {
            QMessageBox::critical(this, tr("Plugin error"), tr("Don`t can load plugin ") + plugin->fileName(), QMessageBox::Close, QMessageBox::Close);
        }
    } else {
        QMessageBox::critical(this, tr("Database error"), tr("Don`t can connect to database ") + db.databaseName(), QMessageBox::Close, QMessageBox::Close);
    }
    if (plugdb.isOpen()) plugdb.close();
    plugdb.removeDatabase("pluginDbRebuild");
}

void ConfigureDialog::on_actionPluginSwitch_state_triggered()
{
    if (modelPlugin->itemFromIndex(modelPlugin->index(ui->tableViewPlugins->currentIndex().row(),0))->checkState() == Qt::Unchecked)
    modelPlugin->itemFromIndex(modelPlugin->index(ui->tableViewPlugins->currentIndex().row(),0))->setCheckState(Qt::Checked);
    else modelPlugin->itemFromIndex(modelPlugin->index(ui->tableViewPlugins->currentIndex().row(),0))->setCheckState(Qt::Unchecked);
}

void ConfigureDialog::mainConnection(QString& host, QString& base, QString& user, QString& passwd)
{
    if (modelConnections->rowCount() > 0) for (int row = 0; row < modelConnections->rowCount(); row++) {
        if (!modelConnections->data(modelConnections->index(row,5)).toString().isEmpty()) {
            host = modelConnections->data(modelConnections->index(row,1)).toString();
            base = modelConnections->data(modelConnections->index(row,2)).toString();
            user = modelConnections->data(modelConnections->index(row,3)).toString();
            passwd = modelConnections->data(modelConnections->index(row,4)).toString();
        }
    }
}
